package edu.sysu.demo.petrabbit.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Slf4j
@Configuration
public class RabbitConfig {


  private static final String BUFFER_QUEUE_NAME = "pet-store-rabbit-buffer-queue";
  public static final String PROCESS_QUEUE_NAME = "pet-store-rabbit-process-queue";

  public static final String BUFFER_EXCHANGE_NAME = "pet-store-rabbit-buffer-exchange";
  private static final String DLX_NAME = "pet-store-rabbit-dlx";

  private static final String PROCESS_QUEUE_ROUTING_KEY = "pet.store.rabbit.delayed.process";
  public static final String BUFFER_EXCHANGE_ROUTING_KEY = "pet.store.rabbit.buffer";

  /**
   * Buffer Queue. Producing dead letters.
   */
  @Bean
  Queue bufferQueue() {
    return QueueBuilder.durable(BUFFER_QUEUE_NAME)
        // DLX
        .withArgument("x-dead-letter-exchange", DLX_NAME)
        // dead letter携带的routing key
        .withArgument("x-dead-letter-routing-key", PROCESS_QUEUE_ROUTING_KEY)
        .build();
  }

  @Bean
  Queue processQueue() {
    return QueueBuilder.durable(PROCESS_QUEUE_NAME)
        .build();
  }

  @Bean
  DirectExchange deadLetterExchange() {
    return new DirectExchange(DLX_NAME);
  }

  @Bean
  DirectExchange bufferExchange() {
    return new DirectExchange(BUFFER_EXCHANGE_NAME);
  }

  @Bean
  Binding dlxBinding() {
    return BindingBuilder.bind(processQueue())
        .to(deadLetterExchange())
        .with(PROCESS_QUEUE_ROUTING_KEY);
  }

  @Bean
  Binding bufferBinding() {
    return BindingBuilder.bind(bufferQueue())
        .to(bufferExchange())
        .with(BUFFER_EXCHANGE_ROUTING_KEY);
  }

  @Bean
  public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(
      ConnectionFactory connectionFactory) {
    SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory);
    factory.setErrorHandler(error -> log.error("Error : {}", error.getClass()));
    return factory;
  }

}
